from typing import List
from enum import Enum
from datetime import time, date

from .Staff import Staff
from .Guarantee import Guarantee
from .Department import Department


class ShiftStyle(Enum):
    Static = 0  # 固定班制
    Turn = 1    # 轮转班制


class TimeSection:
    def __init__(self, 
            start_time: time,       
            end_time: time,         
            is_cross_day: bool = False):    # 是否跨天
        self._start_time = start_time
        self._end_time = end_time
        self._is_cross_day = is_cross_day

    @property
    def start_time(self) -> time:
        return self._start_time

    @property
    def end_time(self) -> time:
        return self._end_time

    @property
    def is_cross_day(self) -> time:
        return self._is_cross_day


class WorkTime:
    def __init__(self, 
            id: int,
            name: str,                              # 班制时间段名称
            time_section_list: List[TimeSection],   # 上班的时间段
            required_staff_cnt: int = None):        # 所需员工数量。主班制此字段为None
        self._id = id
        self._name = name
        self._required_staff_cnt = required_staff_cnt
        self._time_section_list = time_section_list

    @property
    def id(self) -> int:
        return self._id

    @property
    def name(self) -> str:
        return self._name

    @property
    def time_section_list(self) -> List[TimeSection]:
        return self._time_section_list

    @property
    def required_staff_cnt(self) -> int:
        return self._required_staff_cnt

    @required_staff_cnt.setter
    def required_staff_cnt(self, value: int) -> None:
        self._required_staff_cnt = value


class Shift:
    def __init__(self,
            id: int,
            name: str,                  # 班制名称
            duty_days: int,             # 连续上班天数
            rest_days: int,             # 连续休息天数
            style: ShiftStyle,          # 班制类型：固定班制，轮转班制
            is_main: bool,              # 是否是主班制
            worktime_list: List[WorkTime], # 班制中duty_days每天的工作时间，按天数排序
            work_cycle: List = [],      # 工作周期，例：[1,1,0,1,1,0,1]。
                                        # 代表[上，上，休，上，上，休，上]，７天为周期，第３、６天休息。
                                        # 替代duty_days和rest_days。
            ):
        self._id = id
        self._name = name
        self._duty_days = duty_days
        self._rest_days = rest_days
        self._work_cycle = work_cycle
        self._style = style
        self._is_main = is_main
        self._worktime_list = worktime_list

    @property
    def style(self) -> ShiftStyle:
        return self._style

    @property
    def duty_days(self) -> int:
        return self._duty_days

    @property
    def rest_days(self) -> int:
        return self._rest_days

    @property
    def work_cycle(self) -> List:
        return self._work_cycle

    @property
    def worktime_list(self) -> List[WorkTime]:
        return self._worktime_list


class ScheduleUnit:
    def __init__(self,
            id: int,    
            name: str,                      # 排班的最小单元。例如：摆渡排班，可能属于地服公司，可能包含摆渡上客和摆渡下客两个环节
            start_date: date,
            end_date: date,
            staff_list: List[Staff],        # 排班的员工列表
            department: Department,         # 部门
            main_shift: Shift,              # 主班制
            aux_shift: Shift,               # 副班制
            exist_summary = None,           # 当月已执行排班计划总结,
            arrange_data = None,            # 次日排班主班数据（次日排班用）
            overtime_data = None,           # 次日排班副班数据（次日排班用）
            areas = [],                     # 部门区域数据（次日排班用）
            area_data = None,               # 航班与区域数据（次日排班用）
            guarantee_list: List[Guarantee] = [],  # 排班的保障环节列表。例如摆渡上客和摆渡下客。但很多情况下是对应一个保障环节，例如客舱清洁
            task_list: List = [],           # 相应保障环节任务列表
            ):              
        self._id = id
        self._name = name
        self._start_date = start_date
        self._end_date = end_date
        self._staff_list = staff_list
        self._guarantee_list = guarantee_list
        self._department = department
        self._main_shift = main_shift
        self._aux_shift = aux_shift
        self.exist_summary = exist_summary
        self.arrange_data = arrange_data
        self.area_data = area_data
        self.areas = areas
        self.task_list = task_list

    @property
    def id(self):
        return self._id

    @property
    def start_date(self):
        return self._start_date
    
    @property
    def end_date(self):
        return self._end_date

    @property
    def name(self):
        return self._name
        
    @property
    def staff_list(self):
        return self._staff_list
        
    @property
    def guarantee_list(self):
        return self._guarantee_list
        
    @property
    def department(self):
        return self._department
        
    @property
    def main_shift(self):
        return self._main_shift

    @main_shift.setter
    def main_shift(self, shift):
        self._main_shift = shift
    
    @property
    def aux_shift(self):
        return self._aux_shift
    
    @aux_shift.setter
    def aux_shift(self, shift):
        self._aux_shift = shift